package StudyCode.summary.myfile;

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;

/**
 * 版权所有 科技与人文(www.tah1986.com)
 */
public class WatchADirectoryTree {
	public static void main(String[] args) {
		Path path = Paths.get("E:/Copy");
		WatchRecursive watch = new WatchRecursive();
		try {
			watch.watchRNDir(path);
		} catch (IOException | InterruptedException ex) {
			System.err.println(ex);
		}
	}
}

class WatchRecursive {
	private WatchService watchService;
	private final Map<WatchKey, Path> directories = new HashMap<>();

	private void registerTree(Path start) throws IOException {

		Files.walkFileTree(start, new SimpleFileVisitor<Path>() {

			@Override
			public FileVisitResult preVisitDirectory(Path dir,
			                                         BasicFileAttributes attrs) throws IOException {
				System.out.println("Registering:" + dir);
				WatchKey key = dir.register(watchService,
						StandardWatchEventKinds.ENTRY_CREATE,
						StandardWatchEventKinds.ENTRY_MODIFY,
						StandardWatchEventKinds.ENTRY_DELETE);
				directories.put(key, dir);

				return FileVisitResult.CONTINUE;
			}
		});

	}

	public void watchRNDir(Path start) throws IOException, InterruptedException {
		watchService = FileSystems.getDefault().newWatchService();
		registerTree(start);
		while (true) {
			final WatchKey key = watchService.take();
			for (WatchEvent<?> watchEvent : key.pollEvents()) {
				WatchEvent.Kind<?> kind = watchEvent.kind();
				WatchEvent<Path> watchEventPath = (WatchEvent<Path>) watchEvent;
				Path filename = watchEventPath.context();
				if (kind == StandardWatchEventKinds.OVERFLOW) {
					continue;
				}
				if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
					final Path directory_path = directories.get(key);
					final Path child = directory_path.resolve(filename);
					if (Files.isDirectory(child, LinkOption.NOFOLLOW_LINKS)) {
						registerTree(child);
					}
				}
				System.out.println(kind + " -> " + filename);
			}
			boolean valid = key.reset();
			if (!valid) {
				directories.remove(key);
				if (directories.isEmpty()) {
					break;
				}
			}
		}
		watchService.close();
	}
}
